
\chapter{Miscellaneous features}


\section{Comments and declarations}


\index{COMMENT@{\tt COMMENT}}
{\mbox {\tt (COMMENT . {\it comment\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form

\begin{inset}{}
Does nothing and returns no value of interest.
{\tt COMMENT}-expressions may be used to write comments in code.
(The preferred way to write comments, however, is with the semicolon
read macro character; see page \pageref{SEMICOLON}.)
\end{inset} 

\index{IGNORE@{\tt IGNORE}}
{\mbox {\tt (IGNORE . {\it variables\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form

\label{IGNORE}
\begin{inset}{}
Ordinarily, programs
such as compilers
which manipulate source programs
consider it to be an exceptional condition
when a bound variable is not referenced, and may generate warning messages
when they detect this condition.
{\tt IGNORE}-expressions may be used to suppress such warnings
and also to request that a warning be issued if in fact there are
any references to {\it variables\/}.
\begin{codexenv}
(LAMBDA (X Y) (IGNORE X) (CAR Y))
\end{codexenv}
\end{inset} 

\index{IGNORABLE@{\tt IGNORABLE}}
{\mbox {\tt (IGNORABLE . {\it variables\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form

\begin{inset}{}

{\tt IGNORABLE} is like {\tt IGNORE} except that permission is {\it not\/}
given to give warnings if any of {\it variables\/} actually is referenced.
This is not useful for human-generated expressions, but may be useful
in the expansion of a macro invocation where the macro expander may
not know whether a bound variable in the expansion is referenced or
not, and wants to declare that it is all right if the variable is
not referenced.
\end{inset} 

\section{Errors and dead ends}

\label{section:errors}  
\index{ERROR@{\tt ERROR}}
{\mbox {\tt (ERROR {\it control-string\/} . {\it arguments\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Signals an error.  {\it Control-string\/} and {\it arguments\/}
should be arguments suitable for a call to {\tt FORMAT}
(page \pageref{FORMAT}).
The error is reported in an implementation-dependent
manner, and an opportunity is provided to possibly correct
or proceed from the error.  (See section \ref{section:errorsInterface}
for details of {\bf T}'s handling of errors.)
\begin{codexenv}
(ERROR "cannot wash the dishes because $\tilde{}$A" EXCUSE-DESCRIPTION-STRING)
\end{codexenv}
\index{errors}
\end{inset} 

\index{SYNTAX-ERROR@{\tt SYNTAX-ERROR}}
{\mbox {\tt (SYNTAX-ERROR {\it control-string\/} . {\it arguments\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Similar to {\tt ERROR}, but signals a syntax error.
This should be called, for example, from within macro expanders
when an illegal syntax is encountered.
\end{inset} 

\index{READ-ERROR@{\tt READ-ERROR}}
{\mbox {\tt (READ-ERROR {\it port control-string\/} . {\it arguments\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Similar to {\tt ERROR}, but signals a read error.
This should be called, for example, from within read macros
when an illegal read syntax is encountered.
\end{inset} 

\index{CHECK-ARG@{\tt CHECK-ARG}}
{\mbox {\tt (CHECK-ARG {\it predicate object procedure\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
\index{type}
Verifies that an object is of a particular type.
{\it Predicate\/} should be a type predicate, and {\it object\/} can be any object.
If {\it predicate\/}, when applied to {\it object\/}, returns false,
then an error is signalled.
If it returns true, then the {\tt CHECK-ARG} returns {\it object\/}.
{\it Procedure\/} is a procedure whose name will be given in any
message printed by the error system.

The user interface (see section \ref{section:errorsInterface})
may provide a way to supply a value to use in place of {\it object\/}.
If the user attempts to correct the error in this way, then
{\tt CHECK-ARG} again verifies that the new value answers true to
{\it predicate\/}, and returns it.

For example:
{\tt \begin{tabbing}
(DEFINE \= (WASH-DISH DISH) \+ \\
  (LET \= ((DISH (CHECK-ARG DISH? DISH WASH-DISH))) \+ \\
    \ldots\ )) 
\end{tabbing}}
\end{inset} 


\index{ENFORCE@{\tt ENFORCE}}
{\mbox {\tt (ENFORCE {\it predicate\/} {\it value\/}) $\longrightarrow$\  {\it value\/}}}
\hfill  

\begin{inset}{}
Returns {\it value\/} which must answer {\it true} to
{\it predicate\/}.
If {\it predicate\/} returns {\it false} when applied to
{\it value\/}, the effect
is undefined (normally, this means that an error is signalled).
If {\tt ENFORCE} signals an error and enters a breakpoint, then a
new value can be returned using {\tt RET}.  For example,
\begin{codexenv}
    $>$ (LET ((A (ENFORCE FIXNUM? 'A))) (+ A 1)) \\
    $^*$\ $^*$\  Error: (ENFORCE FIXNUM? A) failed in (anonymous) \\
    $>$$>$ (RET 1) \\
    2 \\
    $>$
\end{codexenv}
\end{inset}

\index{UNDEFINED-VALUE@{\tt UNDEFINED-VALUE}}
{\mbox {\tt (UNDEFINED-VALUE . {\it arguments\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill  

\begin{inset}{}
\label{section:undefined}        
\index{undefined}
Has no effect and yields some undefined value.  An implementation will
endeavor to return some object which, when printed or otherwise
displayed, will show the {\it arguments\/}.  This feature may be useful in
debugging, for example in tracking down the origin of the undefined
value, if the value has propagated to an undesirable place.
\end{inset} 

\index{UNDEFINED-EFFECT@{\tt UNDEFINED-EFFECT}}
{\mbox {\tt (UNDEFINED-EFFECT . {\it arguments\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill  

\begin{inset}{}
The effect of calling {\tt UNDEFINED-EFFECT} is undefined.  An
implementation will endeavor to signal an error condition if such a call
ever occurs; however, an optimizing compiler may make use of the fact
that the control path leading to a call to {\tt UNDEFINED-EFFECT} will
never be taken in a correctly running program, and so in some cases may
eliminate the call.
\end{inset} 

\section{Early binding}

\index{early bindings}


\index{DEFINE-CONSTANT@{\tt DEFINE-CONSTANT}}
{\mbox {\tt (DEFINE-CONSTANT {\it variable value\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form

\begin{inset}{}
This is semantically identical to {\tt DEFINE}, but also declares that
the value of the variable will not change.  This might permit a compiler
to perform constant-folding.
Also, if the variable is defined to be a small integer, this may
interact well with {\tt SELECT} to obtain fast numeric dispatch on
``enumerated types''.
\end{inset} 

\index{DEFINE-INTEGRABLE@{\tt DEFINE-INTEGRABLE}}
{\mbox {\tt (DEFINE-INTEGRABLE {\it variable value\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill Special form
\\ {\mbox {\tt (DEFINE-INTEGRABLE ({\it variable\/} . {\it arguments\/}) . {\it body\/}) $\longrightarrow$\  {\it undefined\/}}}

\label{section:defineIntegrable}
\begin{inset}{} 
This is semantically identical to {\tt DEFINE}, but also declares
that the value of the variable is not expected to change.
For example, if a reference to the variable is encountered in
functional position in a call, its definition may be {\it integrated\/},
that is, substituted in-line.
\end{inset}

\section{Symbol generators}

\index{symbol}

\index{GENERATE-SYMBOL@{\tt GENERATE-SYMBOL}}
{\mbox {\tt (GENERATE-SYMBOL {\it prefix\/}) $\longrightarrow$\  {\it symbol\/}}}
\hfill  

\begin{inset}{}
Each call to {\tt GENERATE-SYMBOL} generates a unique identifier.  The
form which the new identifier's name takes is not defined, but the
identifier is guaranteed to be different from any identifier created
in any other way.  The identifier's external representation will begin
with {\it prefix\/}.
\end{inset} 

\index{CONCATENATE-SYMBOL@{\tt CONCATENATE-SYMBOL}}
{\mbox {\tt (CONCATENATE-SYMBOL . {\it things\/}) $\longrightarrow$\  {\it symbol\/}}}
\hfill  

\begin{inset}{}
Creates a symbol whose print name is obtained by appending the printed
representations of {\it things\/} according to the {\tt DISPLAY} operation.
\begin{codexenv}
(CONCATENATE-SYMBOL 'FOO- THING- 34)  $\Longrightarrow$\   FOO-THING-34
\end{codexenv}
\end{inset} 

\section{Combinators}

\index{combinators}

\index{ALWAYS@{\tt ALWAYS}}
{\mbox {\tt (ALWAYS {\it value\/}) $\longrightarrow$\  {\it procedure\/}}}
\hfill  

\begin{inset}{}
Returns a procedure which ignores its arguments and always returns {\it value\/}.
\begin{codexenv}
(ALWAYS {\it value\/}) $\equiv$ (LAMBDA X (IGNORE X) {\it value\/})
\end{codexenv}
\end{inset} 

\index{IDENTITY@{\tt IDENTITY}}
{\mbox {\tt (IDENTITY {\it object\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Identity function.  Returns its argument.
\end{inset} 

\index{PROJN@{\tt PROJN}}
{\mbox {\tt (PROJN {\it n\/}) $\longrightarrow$\  {\it procedure\/}}}
\hfill  

\begin{inset}{}
Returns a procedure which returns (projects) its {\it nth\/} argument, ignoring
any others.
\begin{codexenv}
(PROJN 1)  $\equiv$  (LAMBDA (A B . REST) (IGNORE A REST) B)
\end{codexenv}
\end{inset} 

\index{PROJ0@{\tt PROJ0}}
{\mbox {\tt (PROJ0 {\it object . rest\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Projection function: returns its zeroth argument, ignoring the rest.
\begin{codexenv}
PROJ0  $\equiv$  (PROJN 0)
\end{codexenv}
{\tt PROJ0} is similar to {\tt BLOCK0} (page \pageref{BLOCK0}), except
that it is a procedure, not a special form.
\end{inset} 

\index{PROJ1@{\tt PROJ1}}
{\mbox {\tt (PROJ1 {\it object0 object1 . rest\/}) $\longrightarrow$\  {\it object1\/}}}
\hfill  

\begin{inset}{}
Returns its second argument.
\end{inset} 

\index{PROJ2@{\tt PROJ2}}
{\mbox {\tt (PROJ2 {\it object0 object1 object2 . rest\/}) $\longrightarrow$\  {\it object2\/}}}
\hfill  

\begin{inset}{}
Returns its third argument.
\end{inset} 

\index{PROJ3@{\tt PROJ3}}
{\mbox {\tt (PROJ3 {\it object0 object1 object2 object3 . rest\/}) $\longrightarrow$\  {\it object3\/}}}
\hfill  

\begin{inset}{}
Returns its fourth argument.
\end{inset} 

\index{CONJOIN@{\tt CONJOIN}}
{\mbox {\tt (CONJOIN . {\it predicates\/}) $\longrightarrow$\  {\it predicate\/}}}
\hfill  

\begin{inset}{}
Returns a predicate which is the logical conjunction of all of the
{\it predicates\/}.
\begin{codexenv}
    \begin{tabular}{lll}
((CONJOIN $>$0? ODD?) 13)  &$\Longrightarrow$\ &  {\it true} \\
((CONJOIN $>$0? ODD?) 8)  &$\Longrightarrow$\ &  {\it false}
\end{tabular}
    \end{codexenv}
\end{inset} 

\index{DISJOIN@{\tt DISJOIN}}
{\mbox {\tt (DISJOIN . {\it predicates\/}) $\longrightarrow$\  {\it predicate\/}}}
\hfill  

\begin{inset}{}
Returns a predicate which is the logical disjunction of all of the
{\it predicates\/}.
\begin{codexenv}
    \begin{tabular}{lll}
((DISJOIN $>$0? ODD?) 13)  &$\Longrightarrow$\ &  {\it true} \\
((DISJOIN $>$0? ODD?) 8)  &$\Longrightarrow$\ &  {\it true}
\end{tabular}
    \end{codexenv}
\end{inset} 

\index{COMPLEMENT@{\tt COMPLEMENT}}
{\mbox {\tt (COMPLEMENT {\it predicate\/}) $\longrightarrow$\  {\it predicate\/}}}
\hfill  

\begin{inset}{}
Returns a predicate which is the logical complement of the {\it predicate\/}.
\begin{codexenv}
    \begin{tabular}{lll}
ATOM? &$\equiv$& (COMPLEMENT PAIR?) \\
((COMPLEMENT MEMQ?) 'A '(X Y Z))  &$\Longrightarrow$\ &  {\it true}
\end{tabular}
    \end{codexenv}
\end{inset} 

\index{COMPOSE@{\tt COMPOSE}}
{\mbox {\tt (COMPOSE . {\it procedures\/}) $\longrightarrow$\  {\it procedure\/}}}
\hfill  

\begin{inset}{}
Returns a procedure which is the composition of the {\it procedures\/}.
The last of the {\it procedures\/} may take any number of arguments, and the resulting
procedure will take that same number of arguments; all the other
{\it procedures\/} must take one argument.
{\tt \begin{tabbing}
((COMPOSE CAR CDR) '(A B))   $\Longrightarrow$\   B \\
(COMPLEMENT {\it predicate\/})   $\equiv$  (COMPOSE NOT {\it predicate\/}) \\
PROPER-LIST?   $\equiv$  (DISJOIN NULL? (COMPOSE NULL? CDR LASTCDR)) \\
NTH   $\equiv$  (COMPOSE CAR NTHCDR)
\end{tabbing}}
\end{inset} 


\index{TRUE@{\tt TRUE}}
{\mbox {\tt (TRUE . {\it arguments\/}) $\longrightarrow$\  {\it true\/}}}
\hfill Type predicate

\begin{inset}{}
Ignores its arguments, and always returns true.
This may be used as a predicate representing the ``universal type''
- the type which subsumes all objects.
\end{inset} 

\index{FALSE@{\tt FALSE}}
{\mbox {\tt (FALSE . {\it arguments\/}) $\longrightarrow$\  {\it false\/}}}
\hfill Type predicate

\begin{inset}{}
Ignores its arguments, and always returns false.
This may be used as a predicate representing the ``null type'' - the
type which subsumes no objects.
\end{inset} 

\index{TRUE?@{\tt TRUE?}}
{\mbox {\tt (TRUE? {\it value\/}) $\longrightarrow$\  {\it boolean\/}}}
\hfill Type predicate

\begin{inset}{}
Returns true if {\it value\/} is {\it some\/} true value, false otherwise.
This is convenient where one wants to coerce a truth value
to be a {\it standard\/} truth value; that is,
{\tt TRUE?} maps false to itself, and any true value to
the standard true value ({\tt T}).
\begin{codexenv}
    \begin{tabular}{lll}
(TRUE? {\it object\/})    &$\equiv$&  (NOT (FALSE? {\it object\/})) \\
(TRUE? NIL)  &$\Longrightarrow$\ &  {\it false} \\
(TRUE? T)  &$\Longrightarrow$\ &  {\it true} \\
(TRUE? 3)  &$\Longrightarrow$\ &  {\it true}
\end{tabular}
    \end{codexenv}
\end{inset} 

\index{BOOLEAN?@{\tt BOOLEAN?}}
{\mbox {\tt (BOOLEAN? {\it object\/}) $\longrightarrow$\  {\it boolean\/}}}
\hfill Type predicate

\begin{inset}{}
This returns true if {\it object\/} is either the standard true value
or the standard false value.
\begin{codexenv}
    \begin{tabular}{lll}
(BOOLEAN? NIL)  &$\Longrightarrow$\ &  {\it true} \\
(BOOLEAN? T)    &$\Longrightarrow$\ &  {\it true} \\
(BOOLEAN? 3)    &$\Longrightarrow$\ &  {\it false}
\end{tabular}
    \end{codexenv}
\end{inset} 

\section{Vectors}

\label{section:vectors}  
\index{vectors}

{\it Vectors\/}\index{vectors} can be thought of as
one-dimensional, zero-based arrays, or as fixed-length, random-access lists.
They read and print like lists with a {\tt \#} in front.
Like lists, but unlike numbers and strings, vectors are not
self-evaluating.  To write a constant vector, quote it:
'\#{\mbox {\tt (X Y (1 2))}}.

\index{VECTOR?@{\tt VECTOR?}}
{\mbox {\tt (VECTOR? {\it object\/}) $\longrightarrow$\  {\it boolean\/}}}
\hfill Type predicate

\begin{inset}{}
Returns true if {\it object\/} is a vector.
\end{inset} 

\index{MAKE-VECTOR@{\tt MAKE-VECTOR}}
{\mbox {\tt (MAKE-VECTOR {\it size\/}) $\longrightarrow$\  {\it vector\/}}}
\hfill  

\begin{inset}{}
Returns a vector whose length is {\it size\/}.
The elements are not initialized to any particular value.

{\tt VECTOR-FILL} (see below) may be used
to fill the vector with some useful value (such as {\tt ()}).
\end{inset} 

\index{LIST-$>$VECTOR@{\tt LIST-$>$VECTOR}}
{\mbox {\tt (LIST-$>$VECTOR {\it list\/}) $\longrightarrow$\  {\it vector\/}}}
\hfill  

\begin{inset}{}
Converts a list to a vector.
\begin{codexenv}
(LIST-$>$VECTOR '(A B C))  $\Longrightarrow$\   \#(A B C)
\end{codexenv}
\end{inset} 

\index{VECTOR-$>$LIST@{\tt VECTOR-$>$LIST}}
{\mbox {\tt (VECTOR-$>$LIST {\it vector\/}) $\longrightarrow$\  {\it list\/}}}
\hfill  

\begin{inset}{}
Converts a vector to a list.
\begin{codexenv}
(VECTOR-$>$LIST '\#(A B C))  $\Longrightarrow$\   (A B C)
\end{codexenv}
\end{inset} 

\index{VECTOR-ELT@{\tt VECTOR-ELT}}
{\mbox {\tt (VECTOR-ELT {\it vector n\/}) $\longrightarrow$\  {\it object\/}}}
\hfill Settable

\index{VREF@{\tt VREF}}
{\mbox {\tt (VREF {\it vector n\/}) $\longrightarrow$\  {\it object\/}}}
\hfill Settable

\label{VREF}
\begin{inset}{} 
Accesses the {\it nth\/} element of {\it vector\/} (zero-based).
\begin{codexenv}
(VECTOR-ELT '\#(A B C) 1) $\Longrightarrow$\   B
\end{codexenv}
\end{inset}

\index{VSET@{\tt VSET}}
{\mbox {\tt (VSET {\it vector n object\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Sets the {\it nth\/} element of {\it vector\/} to {\it object\/}.
\begin{codexenv}
(VSET {\it vector n object\/}) $\equiv$ (SET (VREF {\it vector n\/}) {\it object\/})
\end{codexenv}
\end{inset} 

\index{COPY-VECTOR@{\tt COPY-VECTOR}}
{\mbox {\tt (COPY-VECTOR {\it vector\/}) $\longrightarrow$\  {\it vector\/}}}
\hfill  

\begin{inset}{}
Makes a copy of {\it vector\/}.
\end{inset} 

\index{VECTOR-FILL@{\tt VECTOR-FILL}}
{\mbox {\tt (VECTOR-FILL {\it vector value\/}) $\longrightarrow$\  {\it vector\/}}}
\hfill  

\begin{inset}{}
Sets every element of {\it vector\/} to {\it value\/}, and returns the
modified {\it vector\/}.
\end{inset} 

\index{VECTOR-REPLACE@{\tt VECTOR-REPLACE}}
{\mbox {\tt (VECTOR-REPLACE {\it target source n\/}) $\longrightarrow$\  {\it vector\/}}}
\hfill  

\begin{inset}{}
Sets the first {\it n\/} elements of {\it target\/} to be the same as the
corresponding elements of {\it source\/}, and returns the (modified)
{\it target\/}.
\end{inset} 

\index{VECTOR-LENGTH@{\tt VECTOR-LENGTH}}
{\mbox {\tt (VECTOR-LENGTH {\it vector\/}) $\longrightarrow$\  {\it integer\/}}}
\hfill  

\begin{inset}{}
Returns {\it vector\/}'s length.
\end{inset} 

\index{VECTOR-POS@{\tt VECTOR-POS}}
{\mbox {\tt (VECTOR-POS {\it predicate object vector\/}) $\longrightarrow$\  {\it integer\/} {\rm or} {\it false\/}}}
\hfill  

\begin{inset}{}
Returns index of the first element {\it x\/} of {\it vector\/}
such that {\tt ({\it predicate object x\/})}, or false if there is no such element.
\end{inset} 

\index{VECTOR-POSQ@{\tt VECTOR-POSQ}}
{\mbox {\tt (VECTOR-POSQ {\it object vector\/}) $\longrightarrow$\  {\it integer\/} {\rm or} {\it false\/}}}
\hfill  

\begin{inset}{}
\begin{codexenv}
(VECTOR-POSQ {\it object vector\/}) $\equiv$ (VECTOR-POS EQ? {\it object vector\/})
\end{codexenv}
\end{inset} 

\index{WALK-VECTOR@{\tt WALK-VECTOR}}
{\mbox {\tt (WALK-VECTOR {\it procedure vector\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill  

\begin{inset}{}
Applies {\it procedure\/} to every element in {\it vector\/}.
\end{inset} 

\section{Pools}



{\it Pools\/}\index{pools} give a convenient way to perform explicit storage management in T.
One may obtain an object from a pool (popping the pool's free list, or
creating a new object if the free list is empty), and later return an
object to a pool.  By managing storage allocation in this way, the
frequency of garbage collections \index{free lists}

All pools are emptied when a garbage collection occurs.  Garbage
collections occur asynchronously in an implementation-dependent manner.
\index{garbage collection}

\index{MAKE-POOL@{\tt MAKE-POOL}}
{\mbox {\tt (MAKE-POOL {\it identification\/} {\it generator\/}) $\longrightarrow$\  {\it pool\/}}}
\hfill  

\begin{inset}{}
Creates a pool.  {\it Generator\/} should be a procedure, and will be
called by {\tt OBTAIN-FROM-POOL} whenever the pool's free list is empty.
{\it Identification\/} is only for identification purposes, for example,
when the pool is printed.
\end{inset} 

\index{OBTAIN-FROM-POOL@{\tt OBTAIN-FROM-POOL}}
{\mbox {\tt (OBTAIN-FROM-POOL {\it pool\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Obtains an object from {\it pool\/}.  If the pool is empty, the pool's generator
is called to obtain an object, which is then returned directly.
\end{inset} 

\index{RETURN-TO-POOL@{\tt RETURN-TO-POOL}}
{\mbox {\tt (RETURN-TO-POOL {\it pool\/} {\it object\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill  

\begin{inset}{}
Returns {\it object\/} to {\it pool\/}.  A future call to
{\tt OBTAIN-FROM-POOL} may yield {\it object\/}.
\end{inset} 

\section{Weak pointers}


\index{OBJECT-HASH@{\tt OBJECT-HASH}}
{\mbox {\tt (OBJECT-HASH {\it object\/}) $\longrightarrow$\  {\it integer\/}}}
\hfill  

\label{OBJECT-HASH}
\begin{inset}{}
Returns a unique numeric identifier for {\it object\/}.
That is,
\begin{codexenv}
(EQ? {\it object1\/} {\it object2\/})
\end{codexenv}
if and only if
\begin{codexenv}
(= (OBJECT-HASH {\it object1\/}) (OBJECT-HASH {\it object2\/}))
\end{codexenv}
Because {\tt OBJECT-HASH} is invertible (see below), it can be used
to create \ix{weak pointers} to objects, that is, ``pointers'' or
``references'' which are not strong enough to prevent an object from
being reclaimed by the garbage collector.  This concept of weak pointer
is implemented by the integers returned by {\tt OBJECT-HASH}, which
can be dereferenced by calling {\tt OBJECT-UNHASH}.

{\tt OBJECT-HASH} is used by standard methods for the {\tt PRINT} operation
when printing objects which have no read syntax.
\end{inset} 

\index{OBJECT-UNHASH@{\tt OBJECT-UNHASH}}
{\mbox {\tt (OBJECT-UNHASH {\it integer\/}) $\longrightarrow$\  {\it object\/} {\rm or} {\it false\/}}}
\hfill  

\begin{inset}{}
Returns the object whose unique identifier is {\it integer\/},
or false if the object is no longer accessible (e.g. due to garbage
collection).
\begin{codexenv}
(OBJECT-UNHASH (OBJECT-HASH {\it object\/}))  $\Longrightarrow$\   {\it object\/}
\end{codexenv}
\end{inset} 

In {\bf T3}, ``populations'' have been renamed to ``weak-sets''.
This change was made in the belief that ``weak-set'' is a more
intuitive name than ``population''.  The old names are still
supported, but they will be removed in a future release.

{\it Weak-Sets\/}\index{weak sets} provide a way to keep track of a collection of objects.
They are sometimes known as \iix{weak sets} because they behave much like
sets, but an object in a weak-set may go away if the only pointer to
the object is via the weak-set.  The garbage collector will remove
such objects from weak-sets.
\index{garbage collection}

\index{MAKE-WEAK-SET@{\tt MAKE-WEAK-SET}}
{\mbox {\tt (MAKE-WEAK-SET {\it identification\/}) $\longrightarrow$\  {\it weak-set\/}}}
\hfill  

\begin{inset}{}
\index{MAKE-WEAK-SET@{\tt MAKE-WEAK-SET}}
Creates a new weak-set.
\end{inset} 

\index{ADD-TO-WEAK-SET!@{\tt ADD-TO-WEAK-SET!}}
{\mbox {\tt (ADD-TO-WEAK-SET {\it weak-set\/} {\it object\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill  

\begin{inset}{}
\index{ADD-TO-WEAK-SET@{\tt ADD-TO-WEAK-SET}}
Adds {\it object\/} to {\it weak-set\/}.
\end{inset}

\index{REMOVE-FROM-WEAK-SET!@{\tt REMOVE-FROM-WEAK-SET!}}
{\mbox {\tt (REMOVE-FROM-WEAK-SET {\it weak-set\/} {\it object\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill  

\begin{inset}{}
\index{REMOVE-FROM-WEAK-SET@{\tt REMOVE-FROM-WEAK-SET}}
Removes {\it object\/} from {\it weak-set\/}.
\end{inset} 

\index{WEAK-SET-$>$LIST@{\tt WEAK-SET-$>$LIST}}
{\mbox {\tt (WEAK-SET-$>$LIST {\it weak-set\/}) $\longrightarrow$\  {\it list\/}}}
\hfill  

\begin{inset}{}
Returns a list of all objects currently in {\it weak-set\/}.  Note that as
long as this list is accessible, none of the objects will be implicitly
removed from the weak-set, because they will be accessible via this list.
\end{inset} 

\index{WALK-WEAK-SET@{\tt WALK-WEAK-SET}}
{\mbox {\tt (WALK-WEAK-SET {\it weak-set\/} {\it procedure\/}) $\longrightarrow$\  {\it undefined\/}}}
\hfill  

\begin{inset}{}
\index{WALK-WEAK-SET@{\tt WALK-WEAK-SET}}
Calls {\it procedure\/} on each member of {\it weak-set\/}.
\begin{codexenv}
(WALK-WEAK-SET {\it weak-set\/} {\it procedure\/}) \\
  $\equiv$ \\
(WALK {\it procedure\/} (WEAK-SET-$>$LIST {\it weak-set\/}))
\end{codexenv}
\end{inset} 

\index{WEAK-SET-MEMBER?@{\tt WEAK-SET-MEMBER?}}
{\mbox {\tt (WEAK-SET-MEMBER? {\it object weak-set}) $\longrightarrow$\  {\it boolean}}}
\hfill  

\begin{inset}{}
{\mbox {\tt WEAK-SET-MEMBER?}} returns true if {\it object} is a member
of {\it weak-set}; otherwise, it returns false.
\end{inset}

\index{WEAK-SET-EMPTY?@{\tt WEAK-SET-EMPTY?}}
{\mbox {\tt (WEAK-SET-EMPTY? {\it weak-set}) $\longrightarrow$\  {\it boolean}}}
\hfill  

\begin{inset}{}
{\mbox {\tt WEAK-SET-EMPTY?}} returns true if {\it weak-set} is
empty; otherwise, it returns false.
\end{inset}
